package com.aspire.nm.component.miniServer.render.freeMaker;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;

import com.aspire.nm.component.miniServer.render.Render;
import com.aspire.nm.component.miniServer.render.RenderException;

import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;


public class FreeMakerRender implements Render {


    @Override
    public String render(Object data, String source,String encode) throws RenderException {
        try {
            return renderTemplate(getTemplate(source,encode),(Map<?,?>)data);
        } catch (TemplateException e) {
            throw new RenderException(e.toString());
        } catch (IOException e) {
            throw new RenderException(e.toString());
        } catch (GetTemplateException e) {
            throw new RenderException(e.toString());
        }
    }

    
    private HashMap<String,Template> templateMap = new HashMap<String,Template>();
    private Template getTemplate(String filePath,String encode) throws GetTemplateException{
        if(templateMap.get(filePath) == null){
            synchronized(FreeMakerRender.class){
                if(templateMap.get(filePath) == null){
                    File tempLateFile = new File(filePath);
                    if(!tempLateFile.exists() || !tempLateFile.isFile()){
                        throw new GetTemplateException();
                    }else{
                        String dir = tempLateFile.getAbsolutePath().substring(0, tempLateFile.getAbsolutePath().lastIndexOf(tempLateFile.getName()));
                        String fileName = tempLateFile.getName();
                        Configuration config=new Configuration();
                        try {
                            config.setDirectoryForTemplateLoading(new File(dir));
                        } catch (IOException e1) {
                            throw new GetTemplateException(e1.toString());
                        }
                        config.setObjectWrapper(new DefaultObjectWrapper());
                        Template template = null;
                        try {
                            template = config.getTemplate(fileName,encode);
                        } catch (IOException e) {
                            throw new GetTemplateException(e.toString());
                        }
                        templateMap.put(filePath, template);
                    }
                }
            }
        }
        return templateMap.get(filePath);
    }
    
    
    private String renderTemplate(Template template,Map<?,?>root) throws TemplateException, IOException {
        String result;
        Writer out = new StringWriter();
        template.process(root, out);
        result = out.toString();
        out.flush();
        out.close();
        return result;
    }
    
    
    
    private final class GetTemplateException extends Exception {
        public GetTemplateException(){
            super();
        }
        public GetTemplateException(String message){
            super(message);
        }
        private static final long serialVersionUID = 2492923761542712979L;
    }
}
